﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ClassMetadataBrowser.Domain;
using System.Windows.Threading;
using System.Threading;
using Gl.SettingsManager;
using System.Configuration;

namespace ClassMetadataBrowser.UI
{
	/// <summary>
	/// Interaction logic for MetadataBrowser.xaml
	/// </summary>
	public partial class MetadataBrowser : UserControl
	{
		#region Private members

		private IList<MetadataObjectBase> _list;
		private SettingsState _state = new SettingsState();

		protected SettingsState State
		{
			get;
			set;
		}

		#endregion

		#region Properties

		public IHost HostWindow
		{
			get;
			set;
		}

		#endregion

		#region Methods

		public MetadataBrowser()
		{
			InitializeComponent();
		}

		private void SaveSettings()
		{
			Settings settings = Settings.GetSettingsWithConfigurationFileProvider(ConfigurationUserLevel.PerUserRoaming);

			// collecting values from controls
			GridView view = (GridView)_listView.View;
			_state.NameColumnWidth = view.Columns[1].Width;
			_state.ProjectColumnWidth = view.Columns[2].Width;
			_state.Criteria = _txtCriteria.Text;
			settings.Save(_state);
		}

		public void RebindList(IMetadataProvider provider)
		{
			int selectedIndex = _listView.SelectedIndex;
			Filter();
			if (selectedIndex < _listView.Items.Count)
				_listView.SelectedIndex = selectedIndex;
		}

		public void BindMetadata(IMetadataProvider provider)
		{
			_list = provider.Metadata;

			_listView.ItemsSource = null;
			_listView.IsEnabled = true;
			_txtCriteria.IsEnabled = true;

			_panelLoaded.Visibility = Visibility.Visible;
			_panelLoading.Visibility = Visibility.Collapsed;
			_splitor.Visibility = Visibility.Visible;

			_itemsLoaded.Text = string.Format("{0} items loaded", provider.Metadata.Count);

			Filter();
		}

		public void Clear()
		{
			_list = null;

			_panelLoaded.Visibility = Visibility.Collapsed;
			_panelLoading.Visibility = Visibility.Visible;
			_splitor.Visibility = Visibility.Collapsed;
		}

		#endregion

		#region Events and commands handling methods

		private void TxtCriteriaTextChanged(object sender, TextChangedEventArgs e)
		{
			Filter();
		}

		private void Filter()
		{
			if (string.IsNullOrEmpty(_txtCriteria.Text))
			{
				_listView.ItemsSource = _list;
				return;
			}

			_listView.ItemsSource = _list.Where(m => m.Name.ToLower().Contains
				(_txtCriteria.Text.ToLower())).Select(m => m);

			_txtCriteria.CaretIndex = _txtCriteria.Text.Length;
		}

		private void CommandExit(object sender, ExecutedRoutedEventArgs e) { HostWindow.Close(); }

		private void CommandExitCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

		private void CommandSelected(object sender, ExecutedRoutedEventArgs e)
		{
			MetadataObjectBase metadataObject = (MetadataObjectBase)_listView.SelectedItem;
			metadataObject.Navigate();
			SaveSettings();
			HostWindow.Close();
		}

		private void CommandSelectedCanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = _listView.SelectedItem != null;
		}

		private void ListViewMouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			MetadataObjectBase metadataObject = (MetadataObjectBase)_listView.SelectedItem;
			metadataObject.Navigate();
			// focusing back on criteria text box after selection...
		}

		private void TxtCriteriaKeyDown(object sender, KeyEventArgs e)
		{
			switch (e.Key)
			{
				case Key.Up:
					if (_listView.SelectedIndex > 0)
						_listView.SelectedIndex -= 1;
					if (_listView.SelectedIndex < 0)
						_listView.SelectedIndex = 0;
					break;
				case Key.Down:
					if (_listView.SelectedIndex < _listView.Items.Count)
						_listView.SelectedIndex += 1;
					break;
			}

			if (_listView.SelectedItem != null)
			{
				_listView.ScrollIntoView(_listView.SelectedItem);
			}
		}

		private void UserControlLoaded(object sender, RoutedEventArgs e)
		{
			Settings settings = Settings.GetSettingsWithConfigurationFileProvider(ConfigurationUserLevel.PerUserRoaming);
			settings.Load(_state);

			// populating values from controls
			GridView view = (GridView)_listView.View;
			view.Columns[1].Width = _state.NameColumnWidth;
			view.Columns[2].Width = _state.ProjectColumnWidth;
			_txtCriteria.Text = _state.Criteria;
		}

		private void UserControlUnloaded(object sender, RoutedEventArgs e)
		{
			SaveSettings();
		}

		#endregion
	}
}
